package com.googlecode.spruce.schedule;

import java.text.ParseException;
import java.util.List;

import javax.annotation.PostConstruct;

import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.googlecode.spruce.dao.HostDao;
import com.googlecode.spruce.dao.ServiceDao;
import com.googlecode.spruce.dao.ServiceGroupScheduleDao;
import com.googlecode.spruce.domain.ServiceGroupSchedule;

@Service
public class DefaultPluginScheduler implements ScheduledRemotePluginService
{

    private static final Logger logger = LoggerFactory.getLogger(DefaultPluginScheduler.class);

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private ServiceGroupScheduleDao scheduleDao;

    @Autowired
    private ServiceDao serviceDao;

    @Autowired
    private HostDao hostDao;

    @PostConstruct
    @Override
    public void initSchedule()
    {
        final List<ServiceGroupSchedule> schedules = this.scheduleDao.getAll();

        for (final ServiceGroupSchedule schedule : schedules)
        {
            this.schedule(schedule);
        }
    }

    @Override
    public void schedule(final ServiceGroupSchedule serviceGroupSchedule)
    {
        final String jobName = "Service" + serviceGroupSchedule.getId();
        final String triggerName = "Trigger" + serviceGroupSchedule.getId();

        final JobDetail jobDetail = new JobDetail(jobName, "Spruce", RemotePluginJob.class);

        try
        {
            final Trigger trigger = new CronTrigger(triggerName, "Spruce", serviceGroupSchedule.getCron());
            final JobDataMap jobDataMap = new JobDataMap();

            jobDataMap.put("serviceGroupScheduleID", serviceGroupSchedule.getId());

            jobDetail.setJobDataMap(jobDataMap);

            scheduler.scheduleJob(jobDetail, trigger);
        }
        catch (final SchedulerException se)
        {
            logger.error("Error", se);
        }
        catch (final ParseException pe)
        {
            logger.error("Error", pe);
        }
    }

    /**
     * @return the scheduleDao
     */
    public ServiceGroupScheduleDao getScheduleDao()
    {
        return scheduleDao;
    }

    /**
     * @param scheduleDao
     *            the scheduleDao to set
     */
    public void setScheduleDao(final ServiceGroupScheduleDao scheduleDao)
    {
        this.scheduleDao = scheduleDao;
    }

    /**
     * @return the serviceDao
     */
    public ServiceDao getServiceDao()
    {
        return serviceDao;
    }

    /**
     * @param serviceDao
     *            the serviceDao to set
     */
    public void setServiceDao(final ServiceDao serviceDao)
    {
        this.serviceDao = serviceDao;
    }

    /**
     * @return the hostDao
     */
    public HostDao getHostDao()
    {
        return hostDao;
    }

    /**
     * @param hostDao
     *            the hostDao to set
     */
    public void setHostDao(final HostDao hostDao)
    {
        this.hostDao = hostDao;
    }

    /**
     * @return the scheduler
     */
    public Scheduler getScheduler()
    {
        return scheduler;
    }

    /**
     * @param scheduler
     *            the scheduler to set
     */
    public void setScheduler(final Scheduler scheduler)
    {
        this.scheduler = scheduler;
    }

}
